package org.su.webadapter.bind;


import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.su.generalmvc.IEditor;
import org.su.generalmvc.config.BeanMapping;
import org.su.generalmvc.core.InitialContext;
import org.su.generalmvc.entity.PojoCache;
import org.su.webadapter.WebDataBinder;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

/**
 * long数组编辑器，将传入的字符串数组，转换为long数组
 *
 * @author yangchuan
 * @CreateTime 2010-7-29 下午03:03:43
 */
public class ArrayBeanEditor extends AbstractBeanEditor implements IEditor {

    @Override
    public Object getParamValue(String paramName, Class<?> paramType, int paramIndex, Method writer,
                                ServletRequest request, ServletResponse response) {
        if (!isContinueParam(paramName, request)) {
            return null;
        }
        try {
            Class<?> beanType = paramType;
            String typeName = null;
            Collection<Object> result = null;
            boolean isArray = false;
            if (paramType.isArray()) {
                typeName = beanType.getCanonicalName();
                typeName = typeName.substring(0, typeName.length() - 2);
                beanType = Class.forName(typeName);
                result = new ArrayList<>();
                isArray = true;
            } else {
                Type subClass = writer.getGenericParameterTypes()[paramIndex];
                subClass = ((ParameterizedType) subClass).getActualTypeArguments()[0];
                beanType = (Class<?>) subClass;
                typeName = beanType.getName();
                if (Set.class.isAssignableFrom(paramType)) {
                    result = new HashSet<>();
                } else {
                    result = new ArrayList<>();
                }
            }



            IEditor beanEditor = InitialContext.getInstance().getContext().getParamBinder().findEditor(beanType);
            /**
             * 如果为基本类的集合对象
             */
            if (InitialContext.getInstance().getContext().getParamBinder().isBaseEditor(beanType)) {
                String[] values = request.getParameterValues(paramName);
                if (values == null) return null;
                if (values.length == 1 && StringUtils.isBlank(values[0])) {
                    return null;
                }
                AbstractParameterEditor parameterEditor = (AbstractParameterEditor) beanEditor;
                for (String value : values) {
                    result.add(parameterEditor.parseText(value));
                }
                parameterEditor = null;
                return result;
            }

            /**
             * 处理自定义类的集合对象
             */
            String countStr = request.getParameter(paramName + "_count");
            int count = 0;
            if (StringUtils.isNotBlank(countStr)) {
                count = Integer.valueOf(countStr);
                countStr = null;
            }
            count = count - 1;
            Object item = null;
            int j = 0;
            while (true) {
                String prifix = paramName + "[" + j + "]";
                item = beanEditor.getParamValue(prifix, beanType, 0, null,
                        request, response);

                if (item == null && j > count) {
                    break;
                } else {
                    if(item != null) {
                        result.add(item);
                    }
                    j++;
                }
            }

            Object obj = null;
            int len = result.size();
            if (len > 0) {
                if (isArray) {
                    Class<?> paramClazz = Class.forName(typeName);
                    obj = (Object[]) Array.newInstance(paramClazz, len);
                    paramClazz = null;
                    Iterator<Object> items = result.iterator();
                    int i = 0;
                    while (items.hasNext()) {
                        Array.set(obj, i, items.next());
                        i++;
                    }
                } else {
                    obj = result;
                }
            }

            item = null;
            result = null;
            beanEditor = null;
            paramName = null;
            return obj;
        } catch (Exception e) {
            throw new ParamBindException(e, "param name is :" + paramName);
        }
    }




    public static void main(String[] args) throws Exception {
        int i = 0;
        Object result = new HashSet<>();
        Object obj = new Object();
        System.out.println(result.getClass());
        System.out.println(result.getClass().isAssignableFrom(Collection.class));
        System.out.println(Collection.class.isAssignableFrom(obj.getClass()));
    }

    public static  void get(Class<?> paramType) throws Exception {
        System.out.println(((ParameterizedType) paramType.getGenericSuperclass()).getActualTypeArguments()[0]);
        System.out.println(paramType.getCanonicalName());
    }
}
